aiagents4pharma 1.43.0__py3-none-any.whl → 1.44.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiagents4pharma/talk2knowledgegraphs/configs/tools/multimodal_subgraph_extraction/default.yaml +17 -2
- aiagents4pharma/talk2knowledgegraphs/tests/test_tools_milvus_multimodal_subgraph_extraction.py +618 -413
- aiagents4pharma/talk2knowledgegraphs/tests/test_utils_extractions_milvus_multimodal_pcst.py +362 -25
- aiagents4pharma/talk2knowledgegraphs/tools/milvus_multimodal_subgraph_extraction.py +146 -109
- aiagents4pharma/talk2knowledgegraphs/utils/extractions/milvus_multimodal_pcst.py +240 -83
- {aiagents4pharma-1.43.0.dist-info → aiagents4pharma-1.44.0.dist-info}/METADATA +1 -1
- {aiagents4pharma-1.43.0.dist-info → aiagents4pharma-1.44.0.dist-info}/RECORD +10 -10
- {aiagents4pharma-1.43.0.dist-info → aiagents4pharma-1.44.0.dist-info}/WHEEL +0 -0
- {aiagents4pharma-1.43.0.dist-info → aiagents4pharma-1.44.0.dist-info}/licenses/LICENSE +0 -0
- {aiagents4pharma-1.43.0.dist-info → aiagents4pharma-1.44.0.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,9 @@ import unittest
|
|
8
8
|
from unittest.mock import patch, MagicMock, mock_open
|
9
9
|
import numpy as np
|
10
10
|
import pandas as pd
|
11
|
-
from ..utils.extractions.milvus_multimodal_pcst import
|
11
|
+
from ..utils.extractions.milvus_multimodal_pcst import (
|
12
|
+
MultimodalPCSTPruning, SystemDetector, DynamicLibraryLoader
|
13
|
+
)
|
12
14
|
|
13
15
|
class TestMultimodalPCSTPruning(unittest.TestCase):
|
14
16
|
"""
|
@@ -21,29 +23,29 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
|
|
21
23
|
self.addCleanup(patcher_cupy.stop)
|
22
24
|
|
23
25
|
# Patch pcst_fast
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
self.addCleanup(
|
28
|
-
|
26
|
+
pcst_fast_patcher = patch("aiagents4pharma.talk2knowledgegraphs.utils."
|
27
|
+
"extractions.milvus_multimodal_pcst.pcst_fast")
|
28
|
+
mock_pcst_fast = pcst_fast_patcher.start()
|
29
|
+
self.addCleanup(pcst_fast_patcher.stop)
|
30
|
+
mock_pcst_fast.pcst_fast.return_value = ([0, 1], [0])
|
29
31
|
|
30
32
|
# Patch Collection
|
31
|
-
|
32
|
-
|
33
|
-
self.mock_collection =
|
34
|
-
self.addCleanup(
|
33
|
+
collection_patcher = patch("aiagents4pharma.talk2knowledgegraphs.utils."
|
34
|
+
"extractions.milvus_multimodal_pcst.Collection")
|
35
|
+
self.mock_collection = collection_patcher.start()
|
36
|
+
self.addCleanup(collection_patcher.stop)
|
35
37
|
|
36
38
|
# Patch open for cache_edge_index_path
|
37
|
-
|
38
|
-
|
39
|
-
self.addCleanup(
|
39
|
+
open_patcher = patch('builtins.open', mock_open(read_data='[[0,1],[1,2]]'))
|
40
|
+
open_patcher.start()
|
41
|
+
self.addCleanup(open_patcher.stop)
|
40
42
|
|
41
43
|
# Patch pickle.load to return a numpy array for edge_index
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
self.addCleanup(
|
46
|
-
|
44
|
+
pickle_patcher = patch("aiagents4pharma.talk2knowledgegraphs.utils."
|
45
|
+
"extractions.milvus_multimodal_pcst.pickle")
|
46
|
+
mock_pickle = pickle_patcher.start()
|
47
|
+
self.addCleanup(pickle_patcher.stop)
|
48
|
+
mock_pickle.load.return_value = np.array([[0, 1], [1, 2]])
|
47
49
|
|
48
50
|
# Setup config mock
|
49
51
|
self.cfg = MagicMock()
|
@@ -59,6 +61,12 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
|
|
59
61
|
edge_coll.search.return_value = [[MagicMock(id=0, score=1.0), MagicMock(id=1, score=0.5)]]
|
60
62
|
self.mock_collection.side_effect = lambda name: node_coll if "nodes" in name else edge_coll
|
61
63
|
|
64
|
+
# Setup mock loader
|
65
|
+
self.mock_loader = MagicMock()
|
66
|
+
self.mock_loader.py = np # Use numpy for array operations
|
67
|
+
self.mock_loader.df = pd # Use pandas for dataframes
|
68
|
+
self.mock_loader.to_list = lambda x: x.tolist() if hasattr(x, 'tolist') else list(x)
|
69
|
+
|
62
70
|
def test_extract_subgraph_use_description_true(self):
|
63
71
|
"""
|
64
72
|
Test the extract_subgraph method of MultimodalPCSTPruning with use_description=True.
|
@@ -66,7 +74,8 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
|
|
66
74
|
# Create instance
|
67
75
|
pcst = MultimodalPCSTPruning(
|
68
76
|
topk=3, topk_e=3, cost_e=0.5, c_const=0.01, root=-1,
|
69
|
-
num_clusters=1, pruning="gw", verbosity_level=0, use_description=True, metric_type="IP"
|
77
|
+
num_clusters=1, pruning="gw", verbosity_level=0, use_description=True, metric_type="IP",
|
78
|
+
loader=self.mock_loader
|
70
79
|
)
|
71
80
|
# Dummy embeddings
|
72
81
|
text_emb = [0.1, 0.2, 0.3]
|
@@ -89,7 +98,9 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
|
|
89
98
|
# Create instance
|
90
99
|
pcst = MultimodalPCSTPruning(
|
91
100
|
topk=3, topk_e=3, cost_e=0.5, c_const=0.01, root=-1,
|
92
|
-
num_clusters=1, pruning="gw", verbosity_level=0, use_description=False,
|
101
|
+
num_clusters=1, pruning="gw", verbosity_level=0, use_description=False,
|
102
|
+
metric_type="IP",
|
103
|
+
loader=self.mock_loader
|
93
104
|
)
|
94
105
|
# Dummy embeddings
|
95
106
|
text_emb = [0.1, 0.2, 0.3]
|
@@ -111,7 +122,8 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
|
|
111
122
|
"""
|
112
123
|
pcst = MultimodalPCSTPruning(
|
113
124
|
topk=3, topk_e=3, cost_e=0.5, c_const=0.01, root=-1,
|
114
|
-
num_clusters=1, pruning="gw", verbosity_level=0, use_description=True, metric_type="IP"
|
125
|
+
num_clusters=1, pruning="gw", verbosity_level=0, use_description=True, metric_type="IP",
|
126
|
+
loader=self.mock_loader
|
115
127
|
)
|
116
128
|
# Simulate num_nodes = 2, vertices contains [0, 1, 2, 3] (2 and 3 are virtual)
|
117
129
|
num_nodes = 2
|
@@ -150,15 +162,20 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
|
|
150
162
|
with patch.dict("sys.modules", {"cupy": np, "cudf": pd}):
|
151
163
|
# Reload the module to trigger the GPU branch
|
152
164
|
mod = importlib.reload(sys.modules[module_name])
|
153
|
-
|
165
|
+
# Create local mocks for this test
|
166
|
+
mock_pcst_fast = MagicMock()
|
167
|
+
mock_pcst_fast.pcst_fast.return_value = ([0, 1], [0])
|
168
|
+
mock_pickle = MagicMock()
|
169
|
+
mock_pickle.load.return_value = np.array([[0, 1], [1, 2]])
|
170
|
+
# Patch Collection, pcst_fast, and pickle after reload
|
154
171
|
with patch(f"{module_name}.Collection", self.mock_collection), \
|
155
|
-
patch(f"{module_name}.pcst_fast",
|
156
|
-
patch(f"{module_name}.pickle",
|
172
|
+
patch(f"{module_name}.pcst_fast", mock_pcst_fast), \
|
173
|
+
patch(f"{module_name}.pickle", mock_pickle):
|
157
174
|
pcst_pruning_cls = getattr(mod, "MultimodalPCSTPruning")
|
158
175
|
pcst = pcst_pruning_cls(
|
159
176
|
topk=3, topk_e=3, cost_e=0.5, c_const=0.01, root=-1,
|
160
177
|
num_clusters=1, pruning="gw", verbosity_level=0, use_description=True,
|
161
|
-
metric_type="IP"
|
178
|
+
metric_type="IP", loader=self.mock_loader
|
162
179
|
)
|
163
180
|
# Dummy embeddings
|
164
181
|
text_emb = [0.1, 0.2, 0.3]
|
@@ -173,3 +190,323 @@ class TestMultimodalPCSTPruning(unittest.TestCase):
|
|
173
190
|
self.assertIn("edges", result)
|
174
191
|
self.assertGreaterEqual(len(result["nodes"]), 0)
|
175
192
|
self.assertGreaterEqual(len(result["edges"]), 0)
|
193
|
+
|
194
|
+
|
195
|
+
class TestSystemDetector(unittest.TestCase):
|
196
|
+
"""Test cases for SystemDetector class."""
|
197
|
+
|
198
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
199
|
+
'milvus_multimodal_pcst.platform')
|
200
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
201
|
+
'milvus_multimodal_pcst.subprocess')
|
202
|
+
def test_system_detector_gpu_detected(self, mock_subprocess, mock_platform):
|
203
|
+
"""Test SystemDetector when GPU is detected."""
|
204
|
+
# Mock platform calls
|
205
|
+
mock_platform.system.return_value = 'Linux'
|
206
|
+
mock_platform.machine.return_value = 'x86_64'
|
207
|
+
|
208
|
+
# Mock successful nvidia-smi call
|
209
|
+
mock_result = MagicMock()
|
210
|
+
mock_result.returncode = 0
|
211
|
+
mock_subprocess.run.return_value = mock_result
|
212
|
+
|
213
|
+
detector = SystemDetector()
|
214
|
+
|
215
|
+
# Assertions
|
216
|
+
self.assertEqual(detector.os_type, 'linux')
|
217
|
+
self.assertEqual(detector.architecture, 'x86_64')
|
218
|
+
self.assertTrue(detector.has_nvidia_gpu)
|
219
|
+
self.assertTrue(detector.use_gpu)
|
220
|
+
|
221
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
222
|
+
'milvus_multimodal_pcst.platform')
|
223
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
224
|
+
'milvus_multimodal_pcst.subprocess')
|
225
|
+
def test_system_detector_no_gpu(self, mock_subprocess, mock_platform):
|
226
|
+
"""Test SystemDetector when no GPU is detected."""
|
227
|
+
# Mock platform calls
|
228
|
+
mock_platform.system.return_value = 'Linux'
|
229
|
+
mock_platform.machine.return_value = 'x86_64'
|
230
|
+
|
231
|
+
# Mock failed nvidia-smi call
|
232
|
+
mock_result = MagicMock()
|
233
|
+
mock_result.returncode = 1
|
234
|
+
mock_subprocess.run.return_value = mock_result
|
235
|
+
|
236
|
+
detector = SystemDetector()
|
237
|
+
|
238
|
+
# Assertions
|
239
|
+
self.assertEqual(detector.os_type, 'linux')
|
240
|
+
self.assertEqual(detector.architecture, 'x86_64')
|
241
|
+
self.assertFalse(detector.has_nvidia_gpu)
|
242
|
+
self.assertFalse(detector.use_gpu)
|
243
|
+
|
244
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
245
|
+
'milvus_multimodal_pcst.platform')
|
246
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
247
|
+
'milvus_multimodal_pcst.subprocess')
|
248
|
+
def test_system_detector_macos_no_gpu(self, mock_subprocess, mock_platform):
|
249
|
+
"""Test SystemDetector on macOS (no GPU support)."""
|
250
|
+
# Mock platform calls
|
251
|
+
mock_platform.system.return_value = 'Darwin'
|
252
|
+
mock_platform.machine.return_value = 'arm64'
|
253
|
+
|
254
|
+
# Mock successful nvidia-smi call (but macOS should still disable GPU)
|
255
|
+
mock_result = MagicMock()
|
256
|
+
mock_result.returncode = 0
|
257
|
+
mock_subprocess.run.return_value = mock_result
|
258
|
+
|
259
|
+
detector = SystemDetector()
|
260
|
+
|
261
|
+
# Assertions
|
262
|
+
self.assertEqual(detector.os_type, 'darwin')
|
263
|
+
self.assertEqual(detector.architecture, 'arm64')
|
264
|
+
self.assertTrue(detector.has_nvidia_gpu) # GPU detected
|
265
|
+
self.assertFalse(detector.use_gpu) # But not used on macOS
|
266
|
+
|
267
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
268
|
+
'milvus_multimodal_pcst.platform')
|
269
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
270
|
+
'milvus_multimodal_pcst.subprocess')
|
271
|
+
def test_system_detector_subprocess_exception(self, mock_subprocess, mock_platform):
|
272
|
+
"""Test SystemDetector when subprocess raises exception."""
|
273
|
+
# Mock platform calls
|
274
|
+
mock_platform.system.return_value = 'Linux'
|
275
|
+
mock_platform.machine.return_value = 'x86_64'
|
276
|
+
|
277
|
+
# Mock subprocess to raise FileNotFoundError
|
278
|
+
mock_subprocess.run.side_effect = FileNotFoundError("nvidia-smi not found")
|
279
|
+
mock_subprocess.TimeoutExpired = Exception
|
280
|
+
mock_subprocess.SubprocessError = Exception
|
281
|
+
|
282
|
+
detector = SystemDetector()
|
283
|
+
|
284
|
+
# Assertions
|
285
|
+
self.assertEqual(detector.os_type, 'linux')
|
286
|
+
self.assertEqual(detector.architecture, 'x86_64')
|
287
|
+
self.assertFalse(detector.has_nvidia_gpu)
|
288
|
+
self.assertFalse(detector.use_gpu)
|
289
|
+
|
290
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
291
|
+
'milvus_multimodal_pcst.platform')
|
292
|
+
@patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
293
|
+
'milvus_multimodal_pcst.subprocess')
|
294
|
+
def test_system_detector_timeout(self, mock_subprocess, mock_platform):
|
295
|
+
"""Test SystemDetector when subprocess times out."""
|
296
|
+
# Mock platform calls
|
297
|
+
mock_platform.system.return_value = 'Linux'
|
298
|
+
mock_platform.machine.return_value = 'x86_64'
|
299
|
+
|
300
|
+
# Mock subprocess to raise TimeoutExpired
|
301
|
+
mock_subprocess.TimeoutExpired = Exception
|
302
|
+
mock_subprocess.SubprocessError = Exception
|
303
|
+
mock_subprocess.run.side_effect = mock_subprocess.TimeoutExpired("nvidia-smi", 10)
|
304
|
+
|
305
|
+
detector = SystemDetector()
|
306
|
+
|
307
|
+
# Assertions
|
308
|
+
self.assertEqual(detector.os_type, 'linux')
|
309
|
+
self.assertEqual(detector.architecture, 'x86_64')
|
310
|
+
self.assertFalse(detector.has_nvidia_gpu)
|
311
|
+
self.assertFalse(detector.use_gpu)
|
312
|
+
|
313
|
+
def test_get_system_info(self):
|
314
|
+
"""Test get_system_info method."""
|
315
|
+
with patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
316
|
+
'milvus_multimodal_pcst.platform') as mock_platform, \
|
317
|
+
patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
318
|
+
'milvus_multimodal_pcst.subprocess') as mock_subprocess:
|
319
|
+
|
320
|
+
mock_platform.system.return_value = 'Linux'
|
321
|
+
mock_platform.machine.return_value = 'x86_64'
|
322
|
+
|
323
|
+
mock_result = MagicMock()
|
324
|
+
mock_result.returncode = 0
|
325
|
+
mock_subprocess.run.return_value = mock_result
|
326
|
+
|
327
|
+
detector = SystemDetector()
|
328
|
+
info = detector.get_system_info()
|
329
|
+
|
330
|
+
expected_info = {
|
331
|
+
"os_type": "linux",
|
332
|
+
"architecture": "x86_64",
|
333
|
+
"has_nvidia_gpu": True,
|
334
|
+
"use_gpu": True,
|
335
|
+
}
|
336
|
+
self.assertEqual(info, expected_info)
|
337
|
+
|
338
|
+
def test_is_gpu_compatible(self):
|
339
|
+
"""Test is_gpu_compatible method."""
|
340
|
+
with patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
341
|
+
'milvus_multimodal_pcst.platform') as mock_platform, \
|
342
|
+
patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
343
|
+
'milvus_multimodal_pcst.subprocess') as mock_subprocess:
|
344
|
+
|
345
|
+
mock_platform.system.return_value = 'Linux'
|
346
|
+
mock_platform.machine.return_value = 'x86_64'
|
347
|
+
|
348
|
+
mock_result = MagicMock()
|
349
|
+
mock_result.returncode = 0
|
350
|
+
mock_subprocess.run.return_value = mock_result
|
351
|
+
|
352
|
+
detector = SystemDetector()
|
353
|
+
|
354
|
+
# Should be compatible (has GPU + not macOS)
|
355
|
+
self.assertTrue(detector.is_gpu_compatible())
|
356
|
+
|
357
|
+
|
358
|
+
class TestDynamicLibraryLoader(unittest.TestCase):
|
359
|
+
"""Test cases for DynamicLibraryLoader class."""
|
360
|
+
|
361
|
+
def setUp(self):
|
362
|
+
"""Set up test fixtures."""
|
363
|
+
self.mock_detector = MagicMock()
|
364
|
+
|
365
|
+
def test_dynamic_library_loader_cpu_mode(self):
|
366
|
+
"""Test DynamicLibraryLoader in CPU mode."""
|
367
|
+
self.mock_detector.use_gpu = False
|
368
|
+
|
369
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
370
|
+
|
371
|
+
# Assertions
|
372
|
+
self.assertFalse(loader.use_gpu)
|
373
|
+
self.assertEqual(loader.py, np)
|
374
|
+
self.assertEqual(loader.df, pd)
|
375
|
+
self.assertFalse(loader.normalize_vectors)
|
376
|
+
self.assertEqual(loader.metric_type, "COSINE")
|
377
|
+
|
378
|
+
@patch.dict('sys.modules', {'cupy': MagicMock(), 'cudf': MagicMock()})
|
379
|
+
def test_dynamic_library_loader_gpu_mode_success(self):
|
380
|
+
"""Test DynamicLibraryLoader in GPU mode with successful imports."""
|
381
|
+
self.mock_detector.use_gpu = True
|
382
|
+
|
383
|
+
# Mock the CUDF_AVAILABLE flag
|
384
|
+
with patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
385
|
+
'milvus_multimodal_pcst.CUDF_AVAILABLE', True):
|
386
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
387
|
+
|
388
|
+
# Assertions
|
389
|
+
self.assertTrue(loader.use_gpu)
|
390
|
+
self.assertTrue(loader.normalize_vectors)
|
391
|
+
self.assertEqual(loader.metric_type, "IP")
|
392
|
+
|
393
|
+
def test_dynamic_library_loader_gpu_mode_import_failure(self):
|
394
|
+
"""Test DynamicLibraryLoader when GPU libraries are not available."""
|
395
|
+
self.mock_detector.use_gpu = True
|
396
|
+
|
397
|
+
# Mock CUDF_AVAILABLE as False to simulate import failure
|
398
|
+
with patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
399
|
+
'milvus_multimodal_pcst.CUDF_AVAILABLE', False):
|
400
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
401
|
+
|
402
|
+
# Should fallback to CPU mode
|
403
|
+
self.assertFalse(loader.use_gpu)
|
404
|
+
self.assertEqual(loader.py, np)
|
405
|
+
self.assertEqual(loader.df, pd)
|
406
|
+
self.assertFalse(loader.normalize_vectors)
|
407
|
+
self.assertEqual(loader.metric_type, "COSINE")
|
408
|
+
|
409
|
+
def test_normalize_matrix_cpu_mode(self):
|
410
|
+
"""Test normalize_matrix in CPU mode."""
|
411
|
+
self.mock_detector.use_gpu = False
|
412
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
413
|
+
|
414
|
+
matrix = np.array([[1, 2], [3, 4]])
|
415
|
+
result = loader.normalize_matrix(matrix)
|
416
|
+
|
417
|
+
# In CPU mode, should return matrix unchanged
|
418
|
+
np.testing.assert_array_equal(result, matrix)
|
419
|
+
|
420
|
+
def test_normalize_matrix_cpu_mode_normalize_false(self):
|
421
|
+
"""Test normalize_matrix in CPU mode with normalize_vectors=False explicitly."""
|
422
|
+
self.mock_detector.use_gpu = False
|
423
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
424
|
+
|
425
|
+
# Explicitly set normalize_vectors to False to test the return path
|
426
|
+
loader.normalize_vectors = False
|
427
|
+
|
428
|
+
matrix = np.array([[1, 2], [3, 4]])
|
429
|
+
result = loader.normalize_matrix(matrix)
|
430
|
+
|
431
|
+
# Should return matrix unchanged when normalize_vectors is False
|
432
|
+
np.testing.assert_array_equal(result, matrix)
|
433
|
+
|
434
|
+
def test_normalize_matrix_cpu_mode_normalize_true(self):
|
435
|
+
"""Test normalize_matrix in CPU mode with normalize_vectors=True (edge case)."""
|
436
|
+
self.mock_detector.use_gpu = False
|
437
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
438
|
+
|
439
|
+
# Force normalize_vectors to True to test the else branch at line 144
|
440
|
+
loader.normalize_vectors = True
|
441
|
+
loader.use_gpu = False # Ensure GPU is disabled
|
442
|
+
|
443
|
+
matrix = np.array([[1, 2], [3, 4]])
|
444
|
+
result = loader.normalize_matrix(matrix)
|
445
|
+
|
446
|
+
# Should return matrix unchanged in CPU mode even when normalize_vectors is True
|
447
|
+
np.testing.assert_array_equal(result, matrix)
|
448
|
+
|
449
|
+
@patch.dict('sys.modules', {'cupy': MagicMock(), 'cudf': MagicMock()})
|
450
|
+
def test_normalize_matrix_gpu_mode(self):
|
451
|
+
"""Test normalize_matrix in GPU mode."""
|
452
|
+
self.mock_detector.use_gpu = True
|
453
|
+
|
454
|
+
with patch('aiagents4pharma.talk2knowledgegraphs.utils.extractions.'
|
455
|
+
'milvus_multimodal_pcst.CUDF_AVAILABLE', True):
|
456
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
457
|
+
|
458
|
+
# Mock cupy operations
|
459
|
+
mock_cp = MagicMock()
|
460
|
+
mock_array = MagicMock()
|
461
|
+
mock_norms = MagicMock()
|
462
|
+
|
463
|
+
mock_cp.asarray.return_value = mock_array
|
464
|
+
mock_cp.linalg.norm.return_value = mock_norms
|
465
|
+
mock_cp.float32 = np.float32
|
466
|
+
|
467
|
+
loader.cp = mock_cp
|
468
|
+
loader.py = mock_cp
|
469
|
+
|
470
|
+
matrix = [[1, 2], [3, 4]]
|
471
|
+
loader.normalize_matrix(matrix)
|
472
|
+
|
473
|
+
# Verify cupy operations were called
|
474
|
+
mock_cp.asarray.assert_called_once()
|
475
|
+
mock_cp.linalg.norm.assert_called_once()
|
476
|
+
|
477
|
+
def test_to_list_with_tolist(self):
|
478
|
+
"""Test to_list with data that has tolist method."""
|
479
|
+
self.mock_detector.use_gpu = False
|
480
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
481
|
+
|
482
|
+
data = np.array([1, 2, 3])
|
483
|
+
result = loader.to_list(data)
|
484
|
+
|
485
|
+
self.assertEqual(result, [1, 2, 3])
|
486
|
+
|
487
|
+
def test_to_list_with_to_arrow(self):
|
488
|
+
"""Test to_list with data that has to_arrow method."""
|
489
|
+
self.mock_detector.use_gpu = False
|
490
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
491
|
+
|
492
|
+
# Mock data with to_arrow method but no tolist method
|
493
|
+
mock_data = MagicMock()
|
494
|
+
mock_arrow = MagicMock()
|
495
|
+
mock_arrow.to_pylist.return_value = [1, 2, 3]
|
496
|
+
mock_data.to_arrow.return_value = mock_arrow
|
497
|
+
# Remove tolist method to test the to_arrow path
|
498
|
+
del mock_data.tolist
|
499
|
+
|
500
|
+
result = loader.to_list(mock_data)
|
501
|
+
|
502
|
+
self.assertEqual(result, [1, 2, 3])
|
503
|
+
|
504
|
+
def test_to_list_fallback(self):
|
505
|
+
"""Test to_list fallback to list()."""
|
506
|
+
self.mock_detector.use_gpu = False
|
507
|
+
loader = DynamicLibraryLoader(self.mock_detector)
|
508
|
+
|
509
|
+
data = (1, 2, 3) # tuple without tolist or to_arrow
|
510
|
+
result = loader.to_list(data)
|
511
|
+
|
512
|
+
self.assertEqual(result, [1, 2, 3])
|