Skip to content

Commit 86268c9

Browse files
A major updates enabling multiple functional connectivity measures.
1 parent b63b28f commit 86268c9

335 files changed

Lines changed: 68821 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
1.29 MB
Binary file not shown.
1.26 MB
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.\CuCorMat-sca-kendall.exe E:\project\data\4mm E:\project\data\BNU_data_S2_proto-4mm\mask.nii 0.2 n s 1.5 1 0.5
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.\CuCorMat-sca-Pspear.exe E:\project\data\4mm E:\project\data\BNU_data_S2_proto-4mm\mask.nii 0.2 n s p 0.1 1 10

software_package/exefiles_weighted/PC_CPU.BAT renamed to software_package/exefiles_weighted/networkConstruction_scripts.BAT

File renamed without changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
This is the specifications regarding network construction. Three kinds of functional connectivity measures were intergreted in PAGANI toolkit, including Pearson, Kendall, Spearman coefficient of correlation.
2+
Several scripts are provided as name suggests. It's recommendable that users should call network construction functions by altering and running these scripts.
3+
Generally, a standard command template is:
4+
.\CuCorMat-sca-kendall.exe E:\project\data\4mm E:\project\data\BNU_data_S2_proto-4mm\mask.nii 0.2 n s p 0.1 1 10
5+
respcetively to correspond meaning as follows:
6+
procedure_name data_directory mask_file_path mask_threshold to_average network_threshold_type coefficient_type network_threshold_value
7+
Interpretation:
8+
1. procedure_name implies the type of functional connectivity measures you want established newtorks to have. For CuCorMat-sca-Pspear, Pearson and Spearman; For CuCorMat-sca-kendall, Kendall.
9+
1. data_directory is a directory where all files with .nii format will be tackled as the input files of the program.
10+
2. mask_file_path is the path of mask file. Laying mask file in data_directory is generally not recommended since error(s) may occur(s) from time to time.
11+
3. mask_threshold: You guys konw it as name suggests!
12+
4. to_average: this parameter can only be "n" currently. Please dont reason why..
13+
5. network_threshold_type: alternative with "r" or "s". "r" for correlation-value-based thresholding method, and "s" for sparsity-based thresholding method.
14+
6. coefficient_type: "s" for only calculating spearman coefficient of correlation; "p" for for only calculating pearson coefficient of correlation; "sp" or "ps" for calculating both correlation coefficient. Of note,for procedure 'CuCorMat-sca-kendall', no this parameter.
15+
7. network_threshold_value: predicated on parameter network_threshold_type. If network_threshold_type is "r", you can put into multiple values between 0 to 1 spearated by spaces; Else for "s" you can put into multiple values between 0 to 100 without adding sign "%".
16+
Best regards.

software_package/readme.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Here, we developed a parallel graph-theoretical analysis toolkit (PAGANI Toolkit) aiming at fast mapping of voxel-level human brain connectomes, using a hybrid CPU-GPU accelerated framework.
2+
Notably,
3+
1.Majority of functions of PAGANI toolkit is able to be called via GUI except for high-resolution network construction functions.
4+
2.Currently users is suggested to run network construction pocedures on command lines and network analysis procedures by GUI. Regarding cmd tutorials, see .\exefiles_weighted\readmeOnMapDenseConnectomes.txt
5+
3.If users have demands to handle larger connectomes (e.g., with voxel-resolutions equal or less than 2mm), please contact us to gain advanced versions of PAGANI.
6+
Best regards.
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
#include "cublas_v2.h"
2+
#include "cuda_runtime.h"
3+
#include "memory.h"
4+
#include <iostream>
5+
#include <ctime>
6+
# include <fstream>
7+
#include <vector>
8+
#include <Windows.h>
9+
#include<iomanip>
10+
#include <thrust/device_vector.h>
11+
#include"histogram.h"
12+
#include <thrust/binary_search.h>
13+
#include <sm_20_atomic_functions.h>
14+
#include "help_func.cuh"
15+
#include "pre_process.cuh"
16+
17+
//#define width 0.1//0.0001//best to be the multiples
18+
#define width 0.000001//0.0001//best to be the multiples
19+
20+
using namespace std;
21+
#pragma comment(lib,"cublas.lib")
22+
23+
extern __global__ void standardKernel(real__t* devCormat, int Batch_size, bool diagnoal);
24+
25+
void updataPointer(real__t** pointer, real__t* devBOLD, int L, int Batch_size, const int Transferblocknum)
26+
{
27+
*pointer = *pointer == ( devBOLD + L * Batch_size * (Transferblocknum-1) ) ? devBOLD : *pointer + L * Batch_size;
28+
}
29+
void updateDevBOLD(int jj, real__t* devBOLD, real__t* BOLD_t, int L, int Batch_size, int* hosPoint, int* count, real__t* pointer, const int Num_Blocks)
30+
{
31+
if (*count + 1 < Num_Blocks)
32+
{
33+
real__t* devJiAddr = pointer;
34+
if (*hosPoint == Num_Blocks - 1)
35+
{
36+
(*count)++;
37+
(*hosPoint) = (*count);
38+
}
39+
else
40+
(*hosPoint) ++;
41+
real__t* hosJiAddr = BOLD_t + (*hosPoint) * Batch_size * L;
42+
checkCudaErrors( cudaMemcpy(devJiAddr, hosJiAddr, sizeof(real__t) * L * Batch_size, cudaMemcpyHostToDevice) );
43+
}
44+
}
45+
46+
/*
47+
function CorMat_spa2rth
48+
Calculate the correlation threshold for
49+
each sparsity threshold by a histogram method.
50+
*/
51+
real__t CorMat_spa2rth_blocking(string OutCor, real__t * BOLD_t, int N, int L, int Batch_size,real__t *s_thresh, real__t* result, int num_spa, const int Transferblocknum)
52+
{
53+
const int Num_Blocks = (N + Batch_size - 1) / Batch_size;
54+
decltype(N) N0 = Num_Blocks * Batch_size;
55+
size_t L2 = L * ( L - 1 ) / 2;
56+
unsigned long long *zeroAmount = new unsigned long long [num_spa];
57+
for (uint__t i = 0; i < num_spa; i++)
58+
{
59+
unsigned long long amount = N * s_thresh[i] * (N-1) / 100.0 ;///2.0 ;
60+
#ifdef myLiteDebug
61+
cout<<"amount:"<<amount<<endl;
62+
#endif
63+
//amount += amount%2;
64+
zeroAmount[i] = N;
65+
zeroAmount[i] *= N ;
66+
zeroAmount[i] -= amount;
67+
//cout<<zeroAmount[i]<<endl;
68+
}
69+
70+
71+
long long subtractor = (long long)N0 * N0 - (long long)N * N;
72+
uint__t Num_Bins = 1.0 / width + 1; //take care!
73+
#ifdef myLiteDebug
74+
cout<<"Num_Bins:"<<Num_Bins<<endl;
75+
#endif
76+
uint__t position = 0;
77+
// transposing the BOLD signal
78+
cudaError_t cudaStat;
79+
cublasStatus_t stat;
80+
cublasHandle_t handle; //optimize:bitmap+ for 1 -1 0;
81+
real__t * devBOLD, * devCormat, * devBOLD_x, * devBOLD_y;
82+
size_t * tiecount; //perhaps _y _x tiecount should be integer type.
83+
real__t * pointer;
84+
int count = 0; //used to control pointer
85+
int hosPoint = Transferblocknum - 1;
86+
//uint__t *devhisto;
87+
checkCudaErrors ( cudaMalloc ((void**)&devBOLD, sizeof(real__t) * L * Batch_size * Transferblocknum) ) ;
88+
checkCudaErrors ( cudaMalloc ( (void**)&devCormat, sizeof(real__t) * Batch_size * Batch_size) );
89+
checkCudaErrors ( cudaMalloc ((void**)&tiecount, sizeof(size_t) * N0) );
90+
checkCudaErrors ( cudaMalloc ((void**)&devBOLD_x, sizeof(real__t) * L2 * Batch_size) );
91+
checkCudaErrors ( cudaMalloc ((void**)&devBOLD_y, sizeof(real__t) * L2 * Batch_size) );
92+
checkCudaErrors( cudaMemcpy(devBOLD, BOLD_t, sizeof(real__t) * L * Batch_size * Transferblocknum, cudaMemcpyHostToDevice) );
93+
pointer = devBOLD;
94+
stat = cublasCreate(&handle) ;
95+
if (stat != CUBLAS_STATUS_SUCCESS)
96+
return stat;
97+
98+
cout<<"generating histogram..."<<endl;
99+
cout<<"block number per row: "<<Num_Blocks<<endl;
100+
thrust::device_vector<long long> histogram(Num_Bins,0);
101+
clock_t time;
102+
time = clock();
103+
//uint__t blocknum = ( Batch_size * Batch_size + thread_num -1 ) / thread_num;
104+
bool flag = true;
105+
size_t shareSize = sizeof(real__t) * L + sizeof(size_t) * L;
106+
dim3 Grid(Batch_size/thread_num2D, Batch_size/thread_num2D), Block(thread_num2D,thread_num2D);
107+
real__t* biPointer = devBOLD_y;
108+
for (int ii = 0; ii < Num_Blocks; ii++)
109+
{
110+
if ( ii > 0 )
111+
flag = false;
112+
for (int jj = ii; jj < Num_Blocks; jj++)
113+
{
114+
#ifdef myDebug
115+
cout<<"loop flag:"<<ii<<" "<<jj<<endl;
116+
#endif
117+
biPointer = ii == jj ? devBOLD_y : devBOLD_x;
118+
#ifdef figure
119+
int thread_num = L;
120+
int block_num = 180;
121+
#endif
122+
pre_process <<<block_num, thread_num, shareSize>>>(biPointer, pointer, L, L2, Batch_size, tiecount + jj * Batch_size, flag);
123+
checkCublasErrors( cublasSgemm(handle, CUBLAS_OP_T, CUBLAS_OP_N, Batch_size, Batch_size, L2, &alpha, devBOLD_y, L2, biPointer, L2, &beta, devCormat, Batch_size) ); //Is this really right?
124+
dividedByDenominatorAndStandardedKernelWith2DBlock<<<Grid, Block>>>(devCormat, Batch_size, L, tiecount + ii * Batch_size, tiecount + jj * Batch_size, ii==jj);
125+
updateDevBOLD(jj, devBOLD, BOLD_t, L, Batch_size, &hosPoint, &count, pointer, Num_Blocks);
126+
updataPointer(&pointer, devBOLD, L, Batch_size, Transferblocknum);
127+
#ifdef myDebug
128+
//cout<<"loop flag:"<<ii<<" "<<jj<<endl;
129+
gpuOutput(devCormat, sizeof(real__t) * Batch_size * Batch_size, OutCor, true);
130+
if (jj==1)
131+
{
132+
thrust::device_vector<size_t> dt(tiecount,tiecount+129);
133+
print_vector("common!",dt);
134+
}
135+
#endif
136+
if (ii==jj)
137+
dense_histogram(thrust::device_pointer_cast(devCormat),Batch_size * Batch_size, width, Num_Bins, histogram); //Somehow num_bins is generated wrongly in histogram.h files. So just transfer it directly.
138+
else
139+
dense_histogram2(thrust::device_pointer_cast(devCormat),Batch_size * Batch_size, width, Num_Bins, histogram);//difference: Multiply temphisto by 2; Somehow num_bins is generated wrongly in histogram.h files. So just transfer it directly.
140+
}
141+
}
142+
143+
substract(histogram, subtractor); //subtract extra 0 emerged by ending batch
144+
for (size_t i = 0; i < num_spa; i++)
145+
{
146+
//cout<<zeroAmount[i]<<endl;
147+
position = thrust::upper_bound(histogram.begin(),histogram.end(),zeroAmount[i]) - histogram.begin();//flag~ N*N
148+
result[i] = width * position + width/2.0;
149+
#ifdef myLiteDebug
150+
cout<<"threshold:"<<result[i]<<endl;
151+
cout<<position<<endl;
152+
/*cout<<"histogram[position-1]:"<<histogram[position-1]<<endl;
153+
cout<<"histogram[position]:"<<histogram[position]<<endl;
154+
cout<<"histogram[position+1]:"<<histogram[position+1]<<endl;*/
155+
#endif
156+
}
157+
//display and put out
158+
time = clock() - time;
159+
cout<<"histogram time: "<<time<<"ms"<<endl;
160+
161+
checkCudaErrors ( cudaFree (devBOLD));
162+
checkCudaErrors ( cudaFree (devCormat));
163+
checkCudaErrors ( cudaFree (devBOLD_x));
164+
checkCudaErrors ( cudaFree (devBOLD_y));
165+
checkCudaErrors ( cudaFree (tiecount));
166+
167+
/*thrust::adjacent_difference(histogram.begin(), histogram.end(), histogram.begin());
168+
print_vector("histogram:",histogram);*/
169+
thrust::device_vector<long long>().swap(histogram);
170+
171+
delete[] zeroAmount;
172+
stat = cublasDestroy(handle);
173+
if (stat != CUBLAS_STATUS_SUCCESS)
174+
return stat;
175+
176+
}

0 commit comments

Comments
 (0)