|
@@ -47,6 +47,8 @@ bool TransformationReplaceLinearAlgebraInstruction::IsApplicable(
|
|
|
// It must be a supported linear algebra instruction.
|
|
// It must be a supported linear algebra instruction.
|
|
|
if (instruction->opcode() != SpvOpVectorTimesScalar &&
|
|
if (instruction->opcode() != SpvOpVectorTimesScalar &&
|
|
|
instruction->opcode() != SpvOpMatrixTimesScalar &&
|
|
instruction->opcode() != SpvOpMatrixTimesScalar &&
|
|
|
|
|
+ instruction->opcode() != SpvOpVectorTimesMatrix &&
|
|
|
|
|
+ instruction->opcode() != SpvOpMatrixTimesVector &&
|
|
|
instruction->opcode() != SpvOpDot) {
|
|
instruction->opcode() != SpvOpDot) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
@@ -59,9 +61,8 @@ bool TransformationReplaceLinearAlgebraInstruction::IsApplicable(
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// All ids in |message_.fresh_ids| must be fresh.
|
|
// All ids in |message_.fresh_ids| must be fresh.
|
|
|
- for (uint32_t i = 0; i < static_cast<uint32_t>(message_.fresh_ids().size());
|
|
|
|
|
- i++) {
|
|
|
|
|
- if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_ids(i))) {
|
|
|
|
|
|
|
+ for (uint32_t fresh_id : message_.fresh_ids()) {
|
|
|
|
|
+ if (!fuzzerutil::IsFreshId(ir_context, fresh_id)) {
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -81,6 +82,12 @@ void TransformationReplaceLinearAlgebraInstruction::Apply(
|
|
|
case SpvOpMatrixTimesScalar:
|
|
case SpvOpMatrixTimesScalar:
|
|
|
ReplaceOpMatrixTimesScalar(ir_context, linear_algebra_instruction);
|
|
ReplaceOpMatrixTimesScalar(ir_context, linear_algebra_instruction);
|
|
|
break;
|
|
break;
|
|
|
|
|
+ case SpvOpVectorTimesMatrix:
|
|
|
|
|
+ ReplaceOpVectorTimesMatrix(ir_context, linear_algebra_instruction);
|
|
|
|
|
+ break;
|
|
|
|
|
+ case SpvOpMatrixTimesVector:
|
|
|
|
|
+ ReplaceOpMatrixTimesVector(ir_context, linear_algebra_instruction);
|
|
|
|
|
+ break;
|
|
|
case SpvOpDot:
|
|
case SpvOpDot:
|
|
|
ReplaceOpDot(ir_context, linear_algebra_instruction);
|
|
ReplaceOpDot(ir_context, linear_algebra_instruction);
|
|
|
break;
|
|
break;
|
|
@@ -128,6 +135,49 @@ uint32_t TransformationReplaceLinearAlgebraInstruction::GetRequiredFreshIdCount(
|
|
|
->AsVector()
|
|
->AsVector()
|
|
|
->element_count());
|
|
->element_count());
|
|
|
}
|
|
}
|
|
|
|
|
+ case SpvOpVectorTimesMatrix: {
|
|
|
|
|
+ // For each vector component, 1 OpCompositeExtract instruction will be
|
|
|
|
|
+ // inserted. For each matrix column, |1 + vector_component_count|
|
|
|
|
|
+ // OpCompositeExtract, |vector_component_count| OpFMul and
|
|
|
|
|
+ // |vector_component_count - 1| OpFAdd instructions will be inserted.
|
|
|
|
|
+ auto vector_instruction = ir_context->get_def_use_mgr()->GetDef(
|
|
|
|
|
+ instruction->GetSingleWordInOperand(0));
|
|
|
|
|
+ auto matrix_instruction = ir_context->get_def_use_mgr()->GetDef(
|
|
|
|
|
+ instruction->GetSingleWordInOperand(1));
|
|
|
|
|
+ uint32_t vector_component_count =
|
|
|
|
|
+ ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(vector_instruction->type_id())
|
|
|
|
|
+ ->AsVector()
|
|
|
|
|
+ ->element_count();
|
|
|
|
|
+ uint32_t matrix_column_count =
|
|
|
|
|
+ ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(matrix_instruction->type_id())
|
|
|
|
|
+ ->AsMatrix()
|
|
|
|
|
+ ->element_count();
|
|
|
|
|
+ return vector_component_count * (3 * matrix_column_count + 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ case SpvOpMatrixTimesVector: {
|
|
|
|
|
+ // For each matrix column, |1 + matrix_row_count| OpCompositeExtract
|
|
|
|
|
+ // will be inserted. For each matrix row, |matrix_column_count| OpFMul and
|
|
|
|
|
+ // |matrix_column_count - 1| OpFAdd instructions will be inserted. For
|
|
|
|
|
+ // each vector component, 1 OpCompositeExtract instruction will be
|
|
|
|
|
+ // inserted.
|
|
|
|
|
+ auto matrix_instruction = ir_context->get_def_use_mgr()->GetDef(
|
|
|
|
|
+ instruction->GetSingleWordInOperand(0));
|
|
|
|
|
+ uint32_t matrix_column_count =
|
|
|
|
|
+ ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(matrix_instruction->type_id())
|
|
|
|
|
+ ->AsMatrix()
|
|
|
|
|
+ ->element_count();
|
|
|
|
|
+ uint32_t matrix_row_count = ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(matrix_instruction->type_id())
|
|
|
|
|
+ ->AsMatrix()
|
|
|
|
|
+ ->element_type()
|
|
|
|
|
+ ->AsVector()
|
|
|
|
|
+ ->element_count();
|
|
|
|
|
+ return 3 * matrix_column_count * matrix_row_count +
|
|
|
|
|
+ 2 * matrix_column_count - matrix_row_count;
|
|
|
|
|
+ }
|
|
|
case SpvOpDot:
|
|
case SpvOpDot:
|
|
|
// For each pair of vector components, 2 OpCompositeExtract and 1 OpFMul
|
|
// For each pair of vector components, 2 OpCompositeExtract and 1 OpFMul
|
|
|
// will be inserted. The first two OpFMul instructions will result the
|
|
// will be inserted. The first two OpFMul instructions will result the
|
|
@@ -280,6 +330,236 @@ void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesScalar(
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void TransformationReplaceLinearAlgebraInstruction::ReplaceOpVectorTimesMatrix(
|
|
|
|
|
+ opt::IRContext* ir_context,
|
|
|
|
|
+ opt::Instruction* linear_algebra_instruction) const {
|
|
|
|
|
+ // Gets vector information.
|
|
|
|
|
+ auto vector_instruction = ir_context->get_def_use_mgr()->GetDef(
|
|
|
|
|
+ linear_algebra_instruction->GetSingleWordInOperand(0));
|
|
|
|
|
+ uint32_t vector_component_count = ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(vector_instruction->type_id())
|
|
|
|
|
+ ->AsVector()
|
|
|
|
|
+ ->element_count();
|
|
|
|
|
+ auto vector_component_type = ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(vector_instruction->type_id())
|
|
|
|
|
+ ->AsVector()
|
|
|
|
|
+ ->element_type();
|
|
|
|
|
+
|
|
|
|
|
+ // Extracts vector components.
|
|
|
|
|
+ uint32_t fresh_id_index = 0;
|
|
|
|
|
+ std::vector<uint32_t> vector_component_ids(vector_component_count);
|
|
|
|
|
+ for (uint32_t i = 0; i < vector_component_count; i++) {
|
|
|
|
|
+ vector_component_ids[i] = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpCompositeExtract,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type),
|
|
|
|
|
+ vector_component_ids[i],
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {vector_instruction->result_id()}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {i}}})));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Gets matrix information.
|
|
|
|
|
+ auto matrix_instruction = ir_context->get_def_use_mgr()->GetDef(
|
|
|
|
|
+ linear_algebra_instruction->GetSingleWordInOperand(1));
|
|
|
|
|
+ uint32_t matrix_column_count = ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(matrix_instruction->type_id())
|
|
|
|
|
+ ->AsMatrix()
|
|
|
|
|
+ ->element_count();
|
|
|
|
|
+ auto matrix_column_type = ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(matrix_instruction->type_id())
|
|
|
|
|
+ ->AsMatrix()
|
|
|
|
|
+ ->element_type();
|
|
|
|
|
+
|
|
|
|
|
+ std::vector<uint32_t> result_component_ids(matrix_column_count);
|
|
|
|
|
+ for (uint32_t i = 0; i < matrix_column_count; i++) {
|
|
|
|
|
+ // Extracts matrix column.
|
|
|
|
|
+ uint32_t matrix_extract_id = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpCompositeExtract,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(matrix_column_type),
|
|
|
|
|
+ matrix_extract_id,
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {matrix_instruction->result_id()}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {i}}})));
|
|
|
|
|
+
|
|
|
|
|
+ std::vector<uint32_t> float_multiplication_ids(vector_component_count);
|
|
|
|
|
+ for (uint32_t j = 0; j < vector_component_count; j++) {
|
|
|
|
|
+ // Extracts column component.
|
|
|
|
|
+ uint32_t column_extract_id = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpCompositeExtract,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type),
|
|
|
|
|
+ column_extract_id,
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {matrix_extract_id}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {j}}})));
|
|
|
|
|
+
|
|
|
|
|
+ // Multiplies corresponding vector and column components.
|
|
|
|
|
+ float_multiplication_ids[j] = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpFMul,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type),
|
|
|
|
|
+ float_multiplication_ids[j],
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {vector_component_ids[j]}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_ID, {column_extract_id}}})));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Adds the multiplication results.
|
|
|
|
|
+ std::vector<uint32_t> float_add_ids;
|
|
|
|
|
+ uint32_t float_add_id = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ float_add_ids.push_back(float_add_id);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpFAdd,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type), float_add_id,
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {float_multiplication_ids[0]}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_ID, {float_multiplication_ids[1]}}})));
|
|
|
|
|
+ for (uint32_t j = 2; j < float_multiplication_ids.size(); j++) {
|
|
|
|
|
+ float_add_id = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ float_add_ids.push_back(float_add_id);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpFAdd,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type),
|
|
|
|
|
+ float_add_id,
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {float_multiplication_ids[j]}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_ID, {float_add_ids[j - 2]}}})));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ result_component_ids[i] = float_add_ids.back();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // The OpVectorTimesMatrix instruction is changed to an OpCompositeConstruct
|
|
|
|
|
+ // instruction.
|
|
|
|
|
+ linear_algebra_instruction->SetOpcode(SpvOpCompositeConstruct);
|
|
|
|
|
+ linear_algebra_instruction->SetInOperand(0, {result_component_ids[0]});
|
|
|
|
|
+ linear_algebra_instruction->SetInOperand(1, {result_component_ids[1]});
|
|
|
|
|
+ for (uint32_t i = 2; i < result_component_ids.size(); i++) {
|
|
|
|
|
+ linear_algebra_instruction->AddOperand(
|
|
|
|
|
+ {SPV_OPERAND_TYPE_ID, {result_component_ids[i]}});
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fuzzerutil::UpdateModuleIdBound(
|
|
|
|
|
+ ir_context, message_.fresh_ids(message_.fresh_ids().size() - 1));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+void TransformationReplaceLinearAlgebraInstruction::ReplaceOpMatrixTimesVector(
|
|
|
|
|
+ opt::IRContext* ir_context,
|
|
|
|
|
+ opt::Instruction* linear_algebra_instruction) const {
|
|
|
|
|
+ // Gets matrix information.
|
|
|
|
|
+ auto matrix_instruction = ir_context->get_def_use_mgr()->GetDef(
|
|
|
|
|
+ linear_algebra_instruction->GetSingleWordInOperand(0));
|
|
|
|
|
+ uint32_t matrix_column_count = ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(matrix_instruction->type_id())
|
|
|
|
|
+ ->AsMatrix()
|
|
|
|
|
+ ->element_count();
|
|
|
|
|
+ auto matrix_column_type = ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(matrix_instruction->type_id())
|
|
|
|
|
+ ->AsMatrix()
|
|
|
|
|
+ ->element_type();
|
|
|
|
|
+ uint32_t matrix_row_count = matrix_column_type->AsVector()->element_count();
|
|
|
|
|
+
|
|
|
|
|
+ // Extracts matrix columns.
|
|
|
|
|
+ uint32_t fresh_id_index = 0;
|
|
|
|
|
+ std::vector<uint32_t> matrix_column_ids(matrix_column_count);
|
|
|
|
|
+ for (uint32_t i = 0; i < matrix_column_count; i++) {
|
|
|
|
|
+ matrix_column_ids[i] = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpCompositeExtract,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(matrix_column_type),
|
|
|
|
|
+ matrix_column_ids[i],
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {matrix_instruction->result_id()}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {i}}})));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Gets vector information.
|
|
|
|
|
+ auto vector_instruction = ir_context->get_def_use_mgr()->GetDef(
|
|
|
|
|
+ linear_algebra_instruction->GetSingleWordInOperand(1));
|
|
|
|
|
+ auto vector_component_type = ir_context->get_type_mgr()
|
|
|
|
|
+ ->GetType(vector_instruction->type_id())
|
|
|
|
|
+ ->AsVector()
|
|
|
|
|
+ ->element_type();
|
|
|
|
|
+
|
|
|
|
|
+ // Extracts vector components.
|
|
|
|
|
+ std::vector<uint32_t> vector_component_ids(matrix_column_count);
|
|
|
|
|
+ for (uint32_t i = 0; i < matrix_column_count; i++) {
|
|
|
|
|
+ vector_component_ids[i] = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpCompositeExtract,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type),
|
|
|
|
|
+ vector_component_ids[i],
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {vector_instruction->result_id()}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {i}}})));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ std::vector<uint32_t> result_component_ids(matrix_row_count);
|
|
|
|
|
+ for (uint32_t i = 0; i < matrix_row_count; i++) {
|
|
|
|
|
+ std::vector<uint32_t> float_multiplication_ids(matrix_column_count);
|
|
|
|
|
+ for (uint32_t j = 0; j < matrix_column_count; j++) {
|
|
|
|
|
+ // Extracts column component.
|
|
|
|
|
+ uint32_t column_extract_id = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpCompositeExtract,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type),
|
|
|
|
|
+ column_extract_id,
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {matrix_column_ids[j]}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {i}}})));
|
|
|
|
|
+
|
|
|
|
|
+ // Multiplies corresponding vector and column components.
|
|
|
|
|
+ float_multiplication_ids[j] = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpFMul,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type),
|
|
|
|
|
+ float_multiplication_ids[j],
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {column_extract_id}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_ID, {vector_component_ids[j]}}})));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Adds the multiplication results.
|
|
|
|
|
+ std::vector<uint32_t> float_add_ids;
|
|
|
|
|
+ uint32_t float_add_id = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ float_add_ids.push_back(float_add_id);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpFAdd,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type), float_add_id,
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {float_multiplication_ids[0]}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_ID, {float_multiplication_ids[1]}}})));
|
|
|
|
|
+ for (uint32_t j = 2; j < float_multiplication_ids.size(); j++) {
|
|
|
|
|
+ float_add_id = message_.fresh_ids(fresh_id_index++);
|
|
|
|
|
+ float_add_ids.push_back(float_add_id);
|
|
|
|
|
+ linear_algebra_instruction->InsertBefore(MakeUnique<opt::Instruction>(
|
|
|
|
|
+ ir_context, SpvOpFAdd,
|
|
|
|
|
+ ir_context->get_type_mgr()->GetId(vector_component_type),
|
|
|
|
|
+ float_add_id,
|
|
|
|
|
+ opt::Instruction::OperandList(
|
|
|
|
|
+ {{SPV_OPERAND_TYPE_ID, {float_multiplication_ids[j]}},
|
|
|
|
|
+ {SPV_OPERAND_TYPE_ID, {float_add_ids[j - 2]}}})));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ result_component_ids[i] = float_add_ids.back();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // The OpMatrixTimesVector instruction is changed to an OpCompositeConstruct
|
|
|
|
|
+ // instruction.
|
|
|
|
|
+ linear_algebra_instruction->SetOpcode(SpvOpCompositeConstruct);
|
|
|
|
|
+ linear_algebra_instruction->SetInOperand(0, {result_component_ids[0]});
|
|
|
|
|
+ linear_algebra_instruction->SetInOperand(1, {result_component_ids[1]});
|
|
|
|
|
+ for (uint32_t i = 2; i < result_component_ids.size(); i++) {
|
|
|
|
|
+ linear_algebra_instruction->AddOperand(
|
|
|
|
|
+ {SPV_OPERAND_TYPE_ID, {result_component_ids[i]}});
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fuzzerutil::UpdateModuleIdBound(
|
|
|
|
|
+ ir_context, message_.fresh_ids(message_.fresh_ids().size() - 1));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void TransformationReplaceLinearAlgebraInstruction::ReplaceOpDot(
|
|
void TransformationReplaceLinearAlgebraInstruction::ReplaceOpDot(
|
|
|
opt::IRContext* ir_context,
|
|
opt::IRContext* ir_context,
|
|
|
opt::Instruction* linear_algebra_instruction) const {
|
|
opt::Instruction* linear_algebra_instruction) const {
|