1 /*********************************************************************
2 A test program to multithreaded building using Gnuastro's helpers.
3
4 Original author:
5 Mohammad Akhlaghi <mohammad@akhlaghi.org>
6 Contributing author(s):
7 Copyright (C) 2017-2021, Free Software Foundation, Inc.
8
9 Gnuastro is free software: you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation, either version 3 of the License, or (at your
12 option) any later version.
13
14 Gnuastro is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
21 **********************************************************************/
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "gnuastro/fits.h"
26 #include "gnuastro/threads.h"
27
28
29 /* This structure can keep all information you want to pass onto the worker
30 function on each thread. */
31 struct params
32 {
33 gal_data_t *image; /* Dataset to print values of. */
34 };
35
36
37
38
39 /* This is the main worker function which will be called by the different
40 threads. 'gal_threads_params' is defined in 'gnuastro/threads.h' and
41 contains the pointer to the paramter we want. Note that its input and
42 output must have 'void *' types. */
43 void *
worker_on_thread(void * in_prm)44 worker_on_thread(void *in_prm)
45 {
46 /* Low-level definitions to be done first. */
47 struct gal_threads_params *tprm=(struct gal_threads_params *)in_prm;
48 struct params *p=(struct params *)tprm->params;
49
50
51 /* Subsequent definitions. */
52 float *array=p->image->array;
53 size_t i, index, *dsize=p->image->dsize;
54
55
56 /* Go over all the pixels that were assigned to this thread. */
57 for(i=0; tprm->indexs[i] != GAL_BLANK_SIZE_T; ++i)
58 {
59 /* For easy reading. */
60 index = tprm->indexs[i];
61
62
63 /* Print the information. */
64 printf("(%zu, %zu) on thread %zu: %g\n", index%dsize[1]+1,
65 index/dsize[1]+1, tprm->id, array[index]);
66 }
67
68
69 /* Wait for all the other threads to finish, then return. */
70 if(tprm->b) pthread_barrier_wait(tprm->b);
71 return NULL;
72 }
73
74
75
76
77 /* A simple program to open a FITS image, distributes its pixels between
78 different threads and print the value of each pixel and the thread it
79 was assigned to, this will test both the opening of a FITS file and also
80 the multi-threaded functions. After running 'make check' you can see the
81 outputs in 'tests/multithread.log'.
82
83 Please run the following command for an explanation on easily linking
84 and compiling C programs that use Gnuastro's libraries (without having
85 to worry about the libraries to link to) anywhere on your system:
86
87 $ info gnuastro "Automatic linking script"
88 */
89 int
main(void)90 main(void)
91 {
92 struct params p;
93 int quietmmap=1;
94 size_t minmapsize=-1;
95 char *filename="psf.fits", *hdu="1";
96 size_t numthreads=gal_threads_number();
97
98
99 /* Read the image into memory as a float32 data type. */
100 p.image=gal_fits_img_read_to_type(filename, hdu, GAL_TYPE_FLOAT32,
101 minmapsize, quietmmap);
102
103
104 /* Print some basic information before the actual contents: */
105 printf("Pixel values of %s (HDU: %s) on %zu threads.\n", filename, hdu,
106 numthreads);
107 printf("Used to check the compiled library's capability in opening a "
108 "FITS file, and also spinning-off threads.\n");
109
110
111 /* A small sanity check: this is only intended for 2D arrays. */
112 if(p.image->ndim!=2)
113 {
114 fprintf(stderr, "only 2D images are supported.");
115 exit(EXIT_FAILURE);
116 }
117
118
119 /* Spin-off the threads and do the processing on each thread. */
120 gal_threads_spin_off(worker_on_thread, &p, p.image->size, numthreads,
121 minmapsize, quietmmap);
122
123
124 /* Clean up and return. */
125 gal_data_free(p.image);
126 return EXIT_SUCCESS;
127 }
128