diff --git a/.github/workflows/scripts/labeler.js b/.github/workflows/scripts/labeler.js index 769683174688..17205f47cca8 100644 --- a/.github/workflows/scripts/labeler.js +++ b/.github/workflows/scripts/labeler.js @@ -13,37 +13,59 @@ You may obtain a copy of the License at limitations under the License. */ - /** * Invoked from labeler.yaml file to add * label 'Gemma' to the issue and PR for which have gemma keyword present. * @param {!Object.} github contains pre defined functions. - * context Information about the workflow run. + * context Information about the workflow run. */ module.exports = async ({ github, context }) => { - const issue_title = context.payload.issue ? context.payload.issue.title : context.payload.pull_request.title - const issue_description = context.payload.issue ? context.payload.issue.body : context.payload.pull_request.body - const issue_number = context.payload.issue ? context.payload.issue.number : context.payload.pull_request.number + + // Determine if the event is an issue or a pull request. + const isIssue = !!context.payload.issue; + + // Get the issue/PR title, description, and number from the payload. + // Use an empty string for the description if it's null to prevent runtime errors. + const issue_title = isIssue ? context.payload.issue.title : context.payload.pull_request.title; + const issue_description = (isIssue ? context.payload.issue.body : context.payload.pull_request.body) || ''; + const issue_number = isIssue ? context.payload.issue.number : context.payload.pull_request.number; + + // Define the keyword-to-label mapping. const keyword_label = { - gemma:'Gemma' - } - const labelsToAdd = [] - console.log(issue_title,issue_description,issue_number) + gemma: 'Gemma' + }; + // Array to hold labels that need to be added. + const labelsToAdd = []; + + console.log(`Processing event for issue/PR #${issue_number}: "${issue_title}"`); - for(const [keyword, label] of Object.entries(keyword_label)){ - if(issue_title.toLowerCase().indexOf(keyword) !=-1 || issue_description.toLowerCase().indexOf(keyword) !=-1 ){ - console.log(`'${keyword}'keyword is present inside the title or description. Pushing label '${label}' to row.`) - labelsToAdd.push(label) + // Loop through the keywords and check if they exist in the title or description. + for (const [keyword, label] of Object.entries(keyword_label)) { + // Use .includes() for a cleaner and more modern check. + if (issue_title.toLowerCase().includes(keyword) || issue_description.toLowerCase().includes(keyword)) { + console.log(`'${keyword}' keyword is present in the title or description. Pushing label '${label}' to the array.`); + labelsToAdd.push(label); + } + } + + // Add labels if the labelsToAdd array is not empty. + if (labelsToAdd.length > 0) { + console.log(`Adding labels ${labelsToAdd} to issue/PR '#${issue_number}'.`); + + try { + // Await the asynchronous API call to ensure it completes. + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue_number, // Use the correct issue_number variable + labels: labelsToAdd + }); + console.log(`Successfully added labels.`); + } catch (error) { + console.error(`Failed to add labels: ${error.message}`); + } + } else { + console.log("No matching keywords found. No labels to add."); } - } - if(labelsToAdd.length > 0){ - console.log(`Adding labels ${labelsToAdd} to the issue '#${issue_number}'.`) - github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - labels: labelsToAdd - }) - } -}; \ No newline at end of file +}; diff --git a/keras/src/backend/openvino/excluded_concrete_tests.txt b/keras/src/backend/openvino/excluded_concrete_tests.txt index f275493ccbbd..8bf297bcba71 100644 --- a/keras/src/backend/openvino/excluded_concrete_tests.txt +++ b/keras/src/backend/openvino/excluded_concrete_tests.txt @@ -88,7 +88,6 @@ NumpyOneInputOpsCorrectnessTest::test_corrcoef NumpyOneInputOpsCorrectnessTest::test_correlate NumpyOneInputOpsCorrectnessTest::test_cumprod NumpyOneInputOpsCorrectnessTest::test_diag -NumpyOneInputOpsCorrectnessTest::test_diagonal NumpyOneInputOpsCorrectnessTest::test_exp2 NumpyOneInputOpsCorrectnessTest::test_flip NumpyOneInputOpsCorrectnessTest::test_floor_divide diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 251e09c5c785..56751a085c09 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1,6 +1,7 @@ import numpy as np import openvino.opset14 as ov_opset from openvino import Type +from openvino.runtime import opset13 as ov from keras.src.backend import config from keras.src.backend.common import dtypes @@ -17,6 +18,108 @@ from keras.src.backend.openvino.core import ov_to_keras_type +def diagonal(x, offset=0, axis1=0, axis2=1): + x_node = ov.constant(x) # -> ov.Node + offset_const = ov_opset.constant(int(offset), dtype="i64") + + # rank & normalize axes + shape = ov_opset.shape_of(x_node) # i64 vector + rank = ov_opset.shape_of(shape) # scalar i64 (len of shape) + rank_val = ov_opset.squeeze(rank) # [] -> scalar + axis1_node = ov_opset.floor_mod( + ov_opset.add(ov_opset.constant(int(axis1), dtype="i64"), rank_val), + rank_val, + ) + axis2_node = ov_opset.floor_mod( + ov_opset.add(ov_opset.constant(int(axis2), dtype="i64"), rank_val), + rank_val, + ) + + arange = ov_opset.range( + ov_opset.constant(0, dtype="i64"), + rank_val, + ov_opset.constant(1, dtype="i64"), + ) + mask1 = ov_opset.equal(arange, axis1_node) + mask2 = ov_opset.equal(arange, axis2_node) + not12 = ov_opset.logical_not(ov_opset.logical_or(mask1, mask2)) + others = ov_opset.squeeze( + ov_opset.non_zero(not12), [1] + ) # gather positions != axis1, axis2 + perm = ov_opset.concat( + [ + others, + ov_opset.reshape(axis1_node, [1]), + ov_opset.reshape(axis2_node, [1]), + ], + 0, + ) + + x_perm = ov_opset.transpose(x_node, perm) + permuted_shape = ov_opset.shape_of(x_perm) + d1 = ov_opset.gather( + permuted_shape, + ov_opset.constant([-2], dtype="i64"), + ov_opset.constant(0, dtype="i64"), + ) + d2 = ov_opset.gather( + permuted_shape, + ov_opset.constant([-1], dtype="i64"), + ov_opset.constant(0, dtype="i64"), + ) + d1 = ov_opset.squeeze(d1) # scalar + d2 = ov_opset.squeeze(d2) # scalar + + # start1 = max(0, offset), start2 = max(0, -offset) + zero = ov_opset.constant(0, dtype="i64") + start1 = ov_opset.maximum(zero, offset_const) + start2 = ov_opset.maximum(zero, ov_opset.negative(offset_const)) + + # L = min(d1 - start1, d2 - start2) + l1 = ov_opset.subtract(d1, start1) + l2 = ov_opset.subtract(d2, start2) + L = ov_opset.minimum(l1, l2) + + # r = range(0, L, 1) -> shape [L] + r = ov_opset.range(zero, L, ov_opset.constant(1, dtype="i64")) + idx_row = ov_opset.add(r, start1) + idx_col = ov_opset.add(r, start2) + idx_row = ov_opset.unsqueeze( + idx_row, ov_opset.constant(1, dtype="i64") + ) # [L,1] + idx_col = ov_opset.unsqueeze( + idx_col, ov_opset.constant(1, dtype="i64") + ) # [L,1] + diag_idx = ov_opset.concat([idx_row, idx_col], 1) # [L,2] + + # Broadcast indices to batch dims: target shape = (*batch, L, 2) + # batch_rank = rank(x) - 2 + two = ov_opset.constant(2, dtype="i64") + batch_rank = ov_opset.subtract(rank_val, two) + # build target shape: concat(permuted_shape[:batch_rank], [L, 2]) + batch_shape = ov_opset.strided_slice( + permuted_shape, + begin=ov_opset.constant([0], dtype="i64"), + end=ov_opset.reshape(batch_rank, [1]), + strides=ov_opset.constant([1], dtype="i64"), + begin_mask=[0], + end_mask=[0], + ) + target_shape = ov_opset.concat( + [ + batch_shape, + ov_opset.reshape(L, [1]), + ov_opset.constant([2], dtype="i64"), + ], + 0, + ) + bcast_idx = ov_opset.broadcast(diag_idx, target_shape) + + # GatherND with batch_dims = batch_rank + gathered = ov_opset.gather_nd(x_perm, bcast_idx, batch_rank) + + return OpenVINOKerasTensor(gathered) + def add(x1, x2): element_type = None if isinstance(x1, OpenVINOKerasTensor): @@ -677,12 +780,6 @@ def diag(x, k=0): raise NotImplementedError("`diag` is not supported with openvino backend") -def diagonal(x, offset=0, axis1=0, axis2=1): - raise NotImplementedError( - "`diagonal` is not supported with openvino backend" - ) - - def diff(a, n=1, axis=-1): if n == 0: return OpenVINOKerasTensor(get_ov_output(a))