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;
}
Пример #3
0
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;
}
Пример #4
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;
}