char *getDivider(int portion, char *n1, const char *n2) { char *multiplier = strdup("0"); char *tmp = 0; int ret; do { free(tmp); tmp = multiplier; multiplier = add(tmp, "1"); free(tmp); tmp = mult(multiplier, n2); } while (!(ret = isBigger2(tmp, n1, strlen(tmp), portion))); if (!strncmp(tmp, n1, portion)) { free(tmp); return multiplier; } free(tmp); tmp = substract(multiplier, "1"); free(multiplier); if (!strcmp(tmp, "0") && portion + 1 <= strlen(n1)) { free(tmp); return getDivider(portion + 1, n1, n2); } return tmp; }
char *modulo(const char *n1, const char *n2) { int size1, size2, sup; char *tmp, *tmp2, *multi; if (!n1 || !n2) return 0; if (!strcmp(n2, "0")) { return strdup("null"); } if (!strcmp(n2, "1")) { return strdup("0"); } size1 = strlen(n1); size2 = strlen(n2); if (size1 < size2) { return strdup(n1); } if (!strcmp(n1, n2)) { return strdup("0"); } tmp = strdup(n1); while (strcmp(tmp, "0") && isBigger2(tmp, n2, size1, size2)) { sup = getSuperior(size1, size2, tmp, n2); multi = getDivider(sup, tmp, n2); tmp2 = mult(multi, n2); free(multi); multi = getSubstractNumber(tmp, tmp2); free(tmp2); tmp2 = multi; multi = substract(tmp, tmp2); free(tmp); free(tmp2); tmp = multi; size1 = strlen(tmp); if (!strcmp(tmp, n2)) { free(tmp); return strdup("0"); } } return tmp; }
int extract_unary_1D(int mpi_rank,int mpi_size, int ncid,int vlid,int ncidout,int vlidout,int ndims,nc_type vtype,size_t *shape,size_t *begins,size_t *ends, ptrdiff_t *strides,size_t preLen,size_t *outLen){ int i,j,res; size_t *divider=(size_t *)malloc(sizeof(size_t)*ndims); //input divider size_t *dividerOut=(size_t *)malloc(sizeof(size_t)*ndims); // output divider size_t *start=(size_t*)malloc(sizeof(size_t)*ndims); //start position for reading element from input file size_t *count=(size_t*)malloc(sizeof(size_t)*ndims); size_t *countOut=(size_t *)malloc(sizeof(size_t)*ndims); size_t *startOut=(size_t*)malloc(sizeof(size_t)*ndims); //start position for writing element to output file size_t *shapeOut=(size_t*)malloc(sizeof(size_t)*ndims); //output dimension shape size_t startOut0; size_t countOut0; int len0=1; int lenOut=1; for(i=0;i<ndims;++i){ shapeOut[i]=(ends[i]-begins[i])/strides[i]+1; lenOut*=shapeOut[i]; if(i>0){ startOut[i]=0; countOut[i]=shapeOut[i]; start[i]=begins[i]; count[i]=ends[i]-begins[i]+1; len0*=ends[i]-begins[i]+1; } } if(outLen!=NULL) *outLen=lenOut; if(shapeOut[0]>=mpi_size){ startOut0=mpi_rank*(shapeOut[0]/mpi_size); if(mpi_rank!=mpi_size-1){ countOut0=(shapeOut[0]/mpi_size); }else{ countOut0=shapeOut[0]-startOut0; } }else{ if(mpi_rank<shapeOut[0]){ startOut0=mpi_rank; countOut0=1; }else{ return 0; } } int dataEnd=lenOut/shapeOut[0]; void* data=(void*)malloc(sizeof(double)*len0); void* dataOut=(void*)malloc(sizeof(double)*dataEnd); size_t* poses=(size_t*)malloc(sizeof(size_t)*dataEnd); getDivider(ndims,count,divider); getDivider(ndims,countOut,dividerOut); transfer_pos(poses,ndims-1,strides,dataEnd,dividerOut,divider); printf("mpi_rank %d,countOut0 %d\n",mpi_rank,countOut0); for(i=0;i<countOut0;++i){ startOut[0]=startOut0+i+preLen/len0; countOut[0]=1; start[0]=begins[0]+(startOut0+i)*strides[0]; count[0]=1; switch(vtype){ case NC_BYTE: if((res=nc_get_vara_uchar(ncid,vlid,start,count,(unsigned char *)data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_uchar(ncidout,vlidout,startOut,countOut,(unsigned char *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((unsigned char *)dataOut)[j]=((unsigned char *)data)[poses[j]]; } if((res=nc_put_vara_uchar(ncidout,vlidout,startOut,countOut,(unsigned char *)dataOut))) BAIL(res); } break; case NC_CHAR: if((res=nc_get_vara_schar(ncid,vlid,start,count,(signed char *)data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_schar(ncidout,vlidout,startOut,countOut,(signed char *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((signed char *)dataOut)[j]=((signed char *)data)[poses[j]]; } if((res=nc_put_vara_schar(ncidout,vlidout,startOut,countOut,(signed char *)dataOut))) BAIL(res); } break; case NC_SHORT: if((res=nc_get_vara_short(ncid,vlid,start,count,data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_short(ncidout,vlidout,startOut,countOut,(short *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((short *)dataOut)[j]=((short *)data)[poses[j]]; } if((res=nc_put_vara_short(ncidout,vlidout,startOut,countOut,(short *)dataOut))) BAIL(res); } break; case NC_INT: if((res=nc_get_vara_int(ncid,vlid,start,count,(int *)data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_int(ncidout,vlidout,startOut,countOut,(int *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((int *)dataOut)[j]=((int *)data)[poses[j]]; } if((res=nc_put_vara_int(ncidout,vlidout,startOut,countOut,(int *)dataOut))) BAIL(res); } break; case NC_FLOAT: if((res=nc_get_vara_float(ncid,vlid,start,count,data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_float(ncidout,vlidout,startOut,countOut,(float *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((float *)dataOut)[j]=((float *)data)[poses[j]]; } if((res=nc_put_vara_float(ncidout,vlidout,startOut,countOut,(float *)dataOut))) BAIL(res); } break; case NC_DOUBLE: if((res=nc_get_vara_double(ncid,vlid,start,count,(double *)data))) BAIL(res); if(len0==dataEnd){ if((res=nc_put_vara_double(ncidout,vlidout,startOut,countOut,(double *)data))) BAIL(res); }else{ for(j=0;j<dataEnd;++j){ ((double *)dataOut)[j]=((double *)data)[poses[j]]; } if((res=nc_put_vara_double(ncidout,vlidout,startOut,countOut,(double *)dataOut))) BAIL(res); } break; default: printf("Unknown data type\n"); } } /*free resourses*/ free(divider); free(dividerOut); free(start); free(startOut); free(shapeOut); free(data); free(dataOut); free(poses); return 0; }
int extract_unary_single(int mpi_rank,int mpi_size, int ncid,int vlid,int ncidout,int vlidout,int ndims,nc_type vtype,size_t *shape,size_t *begins,size_t *ends, ptrdiff_t *strides,size_t preLen,size_t *outLen){ int i,j,res; size_t *divider=(size_t *)malloc(sizeof(size_t)*ndims); //input divider size_t *dividerOut=(size_t *)malloc(sizeof(size_t)*ndims); // output divider size_t *start=(size_t*)malloc(sizeof(size_t)*ndims); //start position for reading element from input file size_t *startOut=(size_t*)malloc(sizeof(size_t)*ndims); //start position for writing element to output file size_t *shapeOut=(size_t*)malloc(sizeof(size_t)*ndims); //output dimension shape int lenOut=1; for(i=0;i<ndims;++i){ shapeOut[i]=(ends[i]-begins[i])/strides[i]+1; lenOut*=shapeOut[i]; } if(outLen!=NULL) *outLen=lenOut; getDivider(ndims,shape,divider); getDivider(ndims,shapeOut,dividerOut); /* decide element boundary for each mpi process */ size_t beginOut; size_t endOut; if(lenOut>=mpi_size){ beginOut=mpi_rank*(lenOut/mpi_size); if(mpi_rank!=mpi_size-1) endOut=(mpi_rank+1)*(lenOut/mpi_size); else endOut=lenOut; }else{ //mpi_size is bigger than lenOut if(mpi_rank<lenOut){ beginOut=mpi_rank; endOut=mpi_rank+1; }else{ beginOut=0; endOut=0; } } printf("mpi_rank %d, beginOut %d, endOut %d\n",mpi_rank,beginOut,endOut); void *data=malloc(sizeof(double)); size_t rem,remIn; for(i=beginOut;i<endOut;++i){ rem=i+preLen; remIn=i; for(j=0;j<ndims;++j){ startOut[j]=rem/dividerOut[j]; start[j]=begins[j]+(remIn/dividerOut[j])*strides[j]; rem=rem%dividerOut[j]; remIn=remIn%dividerOut[j]; } switch(vtype){ case NC_BYTE: if((res=nc_get_var1_uchar(ncid,vlid,start,data))) BAIL(res); if((res=nc_put_var1_uchar(ncidout,vlidout,startOut,(unsigned char *)data))) BAIL(res); break; case NC_CHAR: if((res=nc_get_var1_schar(ncid,vlid,start,(signed char *)data))) BAIL(res); if((res=nc_put_var1_schar(ncidout,vlidout,startOut,(signed char *)data))) BAIL(res); break; case NC_SHORT: if((res=nc_get_var1_short(ncid,vlid,start,data))) BAIL(res); if((res=nc_put_var1_short(ncidout,vlidout,startOut,(short *)data))) BAIL(res); break; case NC_INT: if((res=nc_get_var1_int(ncid,vlid,start,(int *)data))) BAIL(res); if((res=nc_put_var1_int(ncidout,vlidout,startOut,(int *)data))) BAIL(res); break; case NC_FLOAT: if((res=nc_get_var1_float(ncid,vlid,start,data))) BAIL(res); if((res=nc_put_var1_float(ncidout,vlidout,startOut,(float *)data))) BAIL(res); break; case NC_DOUBLE: if((res=nc_get_var1_double(ncid,vlid,start,data))) BAIL(res); if((res=nc_put_var1_double(ncidout,vlidout,startOut,(double *)data))) BAIL(res); break; default: printf("Unknown data type\n"); } } /*free resourses*/ free(divider); free(dividerOut); free(start); free(startOut); free(shapeOut); free(data); return 0; }
char *divide(const char *n1, const char *n2) { int size1, size2, pos = 0, sup, x, tmp_size, old_size; char *ret, *tmp, *tmp2, *multi; if (!n1 || !n2) return 0; if (!strcmp(n2, "0")) { return strdup("null"); } if (!strcmp(n2, "1")) { return strdup(n1); } size1 = strlen(n1); size2 = strlen(n2); if (size1 < size2) { return strdup("0"); } if (!strcmp(n1, n2)) { return strdup("1"); } ret = malloc(sizeof(*ret) * (size1 + 2)); memset(ret, 0, size1 + 2 * sizeof(*ret)); tmp = strdup(n1); while (strcmp(tmp, "0") && isBigger2(tmp, n2, size1, size2)) { sup = getSuperior(size1, size2, tmp, n2); multi = getDivider(sup, tmp, n2); x = 0; while (multi[x]) ret[pos++] = multi[x++]; tmp2 = mult(multi, n2); tmp_size = strlen(tmp2) - 1; free(multi); multi = getSubstractNumber(tmp, tmp2); free(tmp2); tmp2 = multi; multi = substract(tmp, tmp2); sup = strlen(multi); old_size = size1; x = 0; while (x++ < old_size - sup - size2 - tmp_size) { ret[pos++] = '0'; } free(tmp); free(tmp2); tmp = multi; size1 = strlen(tmp); } free(tmp); tmp = mult(ret, n2); sup = strlen(n1) - strlen(tmp); while (sup-- > 0) ret[pos++] = '0'; free(tmp); --pos; while (pos >= 0) { if (ret[pos] > '9') { if (!pos) { memcpy(ret + 1, ret, size1 + 1); ret[0] = '0'; pos += 1; } ret[pos - 1] += 1; ret[pos] -= 10; } --pos; } if (!ret[0]) ret[0] = '0'; return ret; }