Skip to content
70 changes: 46 additions & 24 deletions .github/workflows/scripts/labeler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.<string,!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
})
}
};
};
1 change: 0 additions & 1 deletion keras/src/backend/openvino/excluded_concrete_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
109 changes: 103 additions & 6 deletions keras/src/backend/openvino/numpy.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can define it once and reuse it throughout the code, since I see the same constant appearing multiple times. This would make the code cleaner and easier to maintain. Please try to clean up the code properly.

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)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, try to avoid broadcast operations, as they tend to increase memory usage.

# 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):
Expand Down Expand Up @@ -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))
Expand Down
Loading