Skip to content

Commit 70bbc87

Browse files
committed
added backend for brick sort and brick sort parallel
1 parent f7a6296 commit 70bbc87

File tree

3 files changed

+167
-0
lines changed

3 files changed

+167
-0
lines changed

pydatastructs/linear_data_structures/_backend/cpp/algorithms/algorithms.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
#include "misc_algorithms.hpp"
55

66
static PyMethodDef algorithms_PyMethodDef[] = {
7+
{"brick_sort_parallel_impl", (PyCFunction) brick_sort_parallel_impl,
8+
METH_VARARGS | METH_KEYWORDS, ""},
9+
{"brick_sort_impl", (PyCFunction) brick_sort_impl,
10+
METH_VARARGS | METH_KEYWORDS, ""},
11+
{"brick_sort", (PyCFunction) brick_sort,
12+
METH_VARARGS | METH_KEYWORDS, ""},
713
{"quick_sort", (PyCFunction) quick_sort,
814
METH_VARARGS | METH_KEYWORDS, ""},
915
{"bubble_sort", (PyCFunction) bubble_sort,

pydatastructs/linear_data_structures/_backend/cpp/algorithms/quadratic_time_sort.hpp

+153
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,157 @@ static PyObject* insertion_sort(PyObject* self, PyObject* args, PyObject* kwds)
185185
}
186186

187187

188+
static PyObject* brick_sort_impl(PyObject* array, size_t lower, size_t upper, PyObject* comp){
189+
bool is_sorted = false;
190+
191+
while(!is_sorted){
192+
is_sorted = true;
193+
194+
for (size_t i = lower + 1; i < upper; i += 2) {
195+
PyObject* i_PyObject = PyLong_FromSize_t(i);
196+
PyObject* i1_PyObject = PyLong_FromSize_t(i + 1);
197+
if (_comp(PyObject_GetItem(array, i_PyObject), PyObject_GetItem(array, i1_PyObject), comp) != 1) {
198+
PyObject* tmp = PyObject_GetItem(array, i1_PyObject);
199+
PyObject_SetItem(array, i1_PyObject, PyObject_GetItem(array, i_PyObject));
200+
PyObject_SetItem(array, i_PyObject, tmp);
201+
is_sorted = false;
202+
}
203+
}
204+
205+
for (size_t i = lower; i < upper; i += 2) {
206+
PyObject* i_PyObject = PyLong_FromSize_t(i);
207+
PyObject* i1_PyObject = PyLong_FromSize_t(i + 1);
208+
if (_comp(PyObject_GetItem(array, i_PyObject), PyObject_GetItem(array, i1_PyObject), comp) != 1) {
209+
PyObject* tmp = PyObject_GetItem(array, i1_PyObject);
210+
PyObject_SetItem(array, i1_PyObject, PyObject_GetItem(array, i_PyObject));
211+
PyObject_SetItem(array, i_PyObject, tmp);
212+
is_sorted = false;
213+
}
214+
}
215+
}
216+
217+
return array;
218+
}
219+
220+
static PyObject* brick_sort(PyObject* self, PyObject* args, PyObject* kwds){
221+
PyObject *args0 = NULL, *start = NULL, *end = NULL;
222+
PyObject *comp = NULL;
223+
size_t lower, upper;
224+
225+
args0 = PyObject_GetItem(args, PyZero);
226+
int is_DynamicOneDimensionalArray = _check_type(args0, &DynamicOneDimensionalArrayType);
227+
int is_OneDimensionalArray = _check_type(args0, &OneDimensionalArrayType);
228+
if (!is_DynamicOneDimensionalArray && !is_OneDimensionalArray) {
229+
raise_exception_if_not_array(args0);
230+
return NULL;
231+
}
232+
233+
comp = PyObject_GetItem(kwds, PyUnicode_FromString("comp"));
234+
if (comp == NULL) {
235+
PyErr_Clear();
236+
}
237+
238+
start = PyObject_GetItem(kwds, PyUnicode_FromString("start"));
239+
if (start == NULL) {
240+
PyErr_Clear();
241+
lower = 0;
242+
} else {
243+
lower = PyLong_AsSize_t(start);
244+
}
245+
246+
end = PyObject_GetItem(kwds, PyUnicode_FromString("end"));
247+
if (end == NULL) {
248+
PyErr_Clear();
249+
upper = PyObject_Length(args0) - 1;
250+
} else {
251+
upper = PyLong_AsSize_t(end);
252+
}
253+
254+
args0 = brick_sort_impl(args0, lower, upper, comp);
255+
if (is_DynamicOneDimensionalArray) {
256+
PyObject_CallMethod(args0, "_modify", "O", Py_True);
257+
}
258+
259+
Py_INCREF(args0);
260+
return args0;
261+
}
262+
263+
264+
static PyObject* brick_sort_parallel_impl(PyObject* array, size_t lower, size_t upper, PyObject* comp) {
265+
bool is_sorted = false;
266+
267+
while (!is_sorted) {
268+
is_sorted = true;
269+
270+
#pragma omp parallel for
271+
for (size_t i = lower + 1; i < upper; i += 2) {
272+
PyObject* i_PyObject = PyLong_FromSize_t(i);
273+
PyObject* i1_PyObject = PyLong_FromSize_t(i + 1);
274+
if (_comp(PyObject_GetItem(array, i_PyObject), PyObject_GetItem(array, i1_PyObject), comp) != 1) {
275+
PyObject* tmp = PyObject_GetItem(array, i1_PyObject);
276+
PyObject_SetItem(array, i1_PyObject, PyObject_GetItem(array, i_PyObject));
277+
PyObject_SetItem(array, i_PyObject, tmp);
278+
is_sorted = false;
279+
}
280+
}
281+
282+
#pragma omp parallel for
283+
for (size_t i = lower; i < upper; i += 2) {
284+
PyObject* i_PyObject = PyLong_FromSize_t(i);
285+
PyObject* i1_PyObject = PyLong_FromSize_t(i + 1);
286+
if (_comp(PyObject_GetItem(array, i_PyObject), PyObject_GetItem(array, i1_PyObject), comp) != 1) {
287+
PyObject* tmp = PyObject_GetItem(array, i1_PyObject);
288+
PyObject_SetItem(array, i1_PyObject, PyObject_GetItem(array, i_PyObject));
289+
PyObject_SetItem(array, i_PyObject, tmp);
290+
is_sorted = false;
291+
}
292+
}
293+
}
294+
295+
return array;
296+
}
297+
298+
static PyObject* brick_sort_parallel(PyObject* self, PyObject* args, PyObject* kwds) {
299+
PyObject *args0 = NULL, *start = NULL, *end = NULL;
300+
PyObject *comp = NULL;
301+
size_t lower, upper;
302+
303+
args0 = PyObject_GetItem(args, PyZero);
304+
int is_DynamicOneDimensionalArray = _check_type(args0, &DynamicOneDimensionalArrayType);
305+
int is_OneDimensionalArray = _check_type(args0, &OneDimensionalArrayType);
306+
if (!is_DynamicOneDimensionalArray && !is_OneDimensionalArray) {
307+
raise_exception_if_not_array(args0);
308+
return NULL;
309+
}
310+
311+
comp = PyObject_GetItem(kwds, PyUnicode_FromString("comp"));
312+
if (comp == NULL) {
313+
PyErr_Clear();
314+
}
315+
316+
start = PyObject_GetItem(kwds, PyUnicode_FromString("start"));
317+
if (start == NULL) {
318+
PyErr_Clear();
319+
lower = 0;
320+
} else {
321+
lower = PyLong_AsSize_t(start);
322+
}
323+
324+
end = PyObject_GetItem(kwds, PyUnicode_FromString("end"));
325+
if (end == NULL) {
326+
PyErr_Clear();
327+
upper = PyObject_Length(args0) - 1;
328+
} else {
329+
upper = PyLong_AsSize_t(end);
330+
}
331+
332+
args0 = brick_sort_parallel_impl(args0, lower, upper, comp);
333+
if (is_DynamicOneDimensionalArray) {
334+
PyObject_CallMethod(args0, "_modify", "O", Py_True);
335+
}
336+
337+
Py_INCREF(args0);
338+
return args0;
339+
}
340+
188341
#endif

pydatastructs/linear_data_structures/algorithms.py

+8
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ def brick_sort(array, **kwargs):
181181
==========
182182
.. [1] https://www.geeksforgeeks.org/odd-even-sort-brick-sort/
183183
"""
184+
backend = kwargs.pop("backend", Backend.PYTHON)
185+
if backend == Backend.CPP:
186+
return _algorithms.brick_sort(array, **kwargs)
187+
184188
raise_if_backend_is_not_python(
185189
brick_sort, kwargs.get('backend', Backend.PYTHON))
186190
start = kwargs.get('start', 0)
@@ -257,6 +261,10 @@ def brick_sort_parallel(array, num_threads, **kwargs):
257261
258262
.. [1] https://en.wikipedia.org/wiki/Odd%E2%80%93even_sort
259263
"""
264+
backend = kwargs.pop("backend", Backend.PYTHON)
265+
if backend == Backend.CPP:
266+
return _algorithms.brick_sort_parallel(array, num_threads, **kwargs)
267+
260268
raise_if_backend_is_not_python(
261269
brick_sort_parallel, kwargs.get('backend', Backend.PYTHON))
262270
start = kwargs.get('start', 0)

0 commit comments

Comments
 (0)