| 1008 | } |
| 1009 | |
| 1010 | static PyObject *NeedlemanWunsch_call(NeedlemanWunsch *self, PyObject *args, PyObject *kwargs) { |
| 1011 | PyObject *a_obj = NULL, *b_obj = NULL, *device_obj = NULL, *out_obj = NULL; |
| 1012 | |
| 1013 | static char *kwlist[] = {"a", "b", "device", "out", NULL}; |
| 1014 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|OO", kwlist, &a_obj, &b_obj, &device_obj, &out_obj)) return NULL; |
| 1015 | |
| 1016 | // Get device handle |
| 1017 | szs_device_scope_t device_handle = default_device_scope; |
| 1018 | if (device_obj && device_obj != Py_None) { |
| 1019 | if (!PyObject_IsInstance(device_obj, (PyObject *)&DeviceScopeType)) { |
| 1020 | PyErr_SetString(PyExc_TypeError, "device must be a DeviceScope instance"); |
| 1021 | return NULL; |
| 1022 | } |
| 1023 | device_handle = ((DeviceScope *)device_obj)->handle; |
| 1024 | } |
| 1025 | |
| 1026 | sz_size_t kernel_input_size = 0; |
| 1027 | void const *kernel_a_texts_punned = NULL; |
| 1028 | void const *kernel_b_texts_punned = NULL; |
| 1029 | sz_status_t (*kernel_punned)(szs_needleman_wunsch_scores_t, szs_device_scope_t, void const *, void const *, |
| 1030 | sz_ssize_t *, sz_size_t, char const **) = NULL; |
| 1031 | |
| 1032 | // Swap allocators only when using CUDA with a GPU device (inputs must be unified) |
| 1033 | if (requires_unified_memory(self->capabilities)) |
| 1034 | if (!try_swap_to_unified_allocator(a_obj) || !try_swap_to_unified_allocator(b_obj)) return NULL; |
| 1035 | |
| 1036 | // Handle 32-bit tape inputs |
| 1037 | sz_sequence_u32tape_t a_u32tape, b_u32tape; |
| 1038 | sz_bool_t a_is_u32tape = sz_py_export_strings_as_u32tape( // |
| 1039 | a_obj, &a_u32tape.data, &a_u32tape.offsets, &a_u32tape.count); |
| 1040 | sz_bool_t b_is_u32tape = sz_py_export_strings_as_u32tape( // |
| 1041 | b_obj, &b_u32tape.data, &b_u32tape.offsets, &b_u32tape.count); |
| 1042 | if (a_is_u32tape && b_is_u32tape) { |
| 1043 | if (a_u32tape.count != b_u32tape.count) { |
| 1044 | PyErr_SetString(PyExc_ValueError, "Input sequences must have the same length"); |
| 1045 | return NULL; |
| 1046 | } |
| 1047 | kernel_input_size = a_u32tape.count; |
| 1048 | kernel_punned = szs_needleman_wunsch_scores_u32tape; |
| 1049 | kernel_a_texts_punned = &a_u32tape; |
| 1050 | kernel_b_texts_punned = &b_u32tape; |
| 1051 | } |
| 1052 | |
| 1053 | // Handle 64-bit tape inputs |
| 1054 | sz_sequence_u64tape_t a_u64tape, b_u64tape; |
| 1055 | sz_bool_t a_is_u64tape = !a_is_u32tape && sz_py_export_strings_as_u64tape( // |
| 1056 | a_obj, &a_u64tape.data, &a_u64tape.offsets, &a_u64tape.count); |
| 1057 | sz_bool_t b_is_u64tape = !b_is_u32tape && sz_py_export_strings_as_u64tape( // |
| 1058 | b_obj, &b_u64tape.data, &b_u64tape.offsets, &b_u64tape.count); |
| 1059 | if (a_is_u64tape && b_is_u64tape) { |
| 1060 | if (a_u64tape.count != b_u64tape.count) { |
| 1061 | PyErr_SetString(PyExc_ValueError, "Input sequences must have the same length"); |
| 1062 | return NULL; |
| 1063 | } |
| 1064 | kernel_input_size = a_u64tape.count; |
| 1065 | kernel_punned = szs_needleman_wunsch_scores_u64tape; |
| 1066 | kernel_a_texts_punned = &a_u64tape; |
| 1067 | kernel_b_texts_punned = &b_u64tape; |
nothing calls this directly
no test coverage detected
searching dependent graphs…